package com.cybertron.ironhide.solr.analysis;

import java.io.IOException;

import org.apache.commons.collections.MapUtils;
import org.apache.lucene.analysis.TokenFilter;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
import org.apache.lucene.analysis.util.CharArrayMap;

public class TagGeneratorFilter extends TokenFilter {

	private final CharArrayMap<CharArrayMap<String>> words;

	private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class);

	private final PositionIncrementAttribute posIncrAtt = addAttribute(PositionIncrementAttribute.class);

	private String cateId;

	public TagGeneratorFilter(TokenStream in,
			CharArrayMap<CharArrayMap<String>> words) {
		super(in);
		this.words = words;
	}

	private boolean accept() throws IOException {
		if (cateId == null) {
			return false;
		}
		CharArrayMap<String> dicMap = words.get(cateId);
		if (dicMap == null) {
			return false;
		}
		return dicMap.containsKey(termAtt.buffer(), 0, termAtt.length());
	}

	@Override
	public final boolean incrementToken() throws IOException {
		int skippedPositions = 0;
		while (input.incrementToken()) {
			if (skippedPositions == 0) {
				if (words.containsKey(termAtt)) {
					cateId = new String(termAtt.toString());
				}
			}
			if (accept()) {
				if (skippedPositions != 0) {
					posIncrAtt.setPositionIncrement(posIncrAtt
							.getPositionIncrement() + skippedPositions);
				}
				if (cateId == null) {
					return false;
				}
				String val = MapUtils.getString(words.get(cateId), termAtt);
				if (val == null) {
					return false;
				}
				return true;
			}
			skippedPositions += posIncrAtt.getPositionIncrement();
		}
		return false;
	}
}
